program BINARYTREE(INPUT,OUTPUT);
{$U+}
 type
   TREEPNTR = ^TREERECORD;
   TREERECORD=RECORD
      LEFT:TREEPNTR;
      MNEMONIC:string[7];
      OPCODE:string[5];
      RIGHT:TREEPNTR
     end;
   DATA=record
     MNEMONIC:string[7];
     OPCODE:string[5]
    end;
   DATAFIL=file of data;
 var
   CURRENT,FIRST,TEMP,R,P,B:treepntr;
                        num:string[3];
                        elt:string[5];
                     choice:char;
                      found:boolean;
                        fil:datafil;
                        dat:data;

procedure CREATE(var fil:datafil);
 var
   items:data;
 begin
   CLRSCR;
   ASSIGN(FIL,'Code.pas');
   REWRITE(FIL);
   WRITELN;
   WRITELN('------------------');
   WRITELN('DATA FILE OF CODE ');
   WRITELN('------------------');
   WRITELN;
   WRITELN('GIVE: OPCODE= "#" TO STOP');
   WRITELN;
   WRITELN;
   WRITE('ENTER THE OPCODE :  ');
   READLN(ITEMS.OPCODE);
   WRITELN;
   WRITELN;
   if (ITEMS.OPCODE<> #) then
     begin
       WRITE('ENTER THE MNEMONIC :  ');
       READLN(ITEMS.MNEMONIC);
       if  ITEMS.OPCODE<>'#' THEN
          WRITE(FIL,items);
     end;
   CLOSE(FIL);
 end;

procedure INSERT(var CURRENT:TREEPNTR);
  begin
    if CURRENT=NIL then
      begin
        new(CURRENT);
        CURRENT^.MNEMONIC:=elt;
        CURRENT^.OPCODE:=num;
        CURRENT^.LEFT:=nil;
        CURRENT^.RIGHT:=nil;
      end
    else
      if num<CURRENT^.OPCODE then
         insert(CURRENT^.LEFT)
      else
         insert(CURRENT^.RIGHT);
  end; {INSERT}

procedure DELETE(var R:treepntr;
                     P,B:treepntr);
  {Deletes node pointed ti by p from binary }
  {tree with root pointer ROOT  }
  var
     tem:treepntr;
  begin
    {if node(P) is a leaf}
    if(P^.RIGHT= NIL) and (P^.LEFT= NIL) then
      if B = NIL then         {node(P) is the last node in tree}
         R:=NIL
      else
       if B^.RIGHT=P then
          B^.RIGHT:=NIL
       else
          B^.LEFT:=NIL
       else
         if (P^.RIGHT<>NIL) and (P^.LEFT<>NIL) then
           begin
             {initialize pointers for search }
             {for replacement value}
             B:=P;
             TEM:=P^.LEFT;
             {locate node containing closest value }
             {less than the one being deleted }
             while TEM^.RIGHT<>NIL do
               begin
                 B:=TEM;
                 TEM:=TEM^.RIGHT;
               end;{while}
             {put replacement value into the node}
             {whose value is being deleted}
             P^.MNEMONIC:=TEM^.MNEMONIC;
             {DELETE THE NODE FROM WHICH REPLACEMENT}
             {VALUE WAS TAKEN }
             if B=P then
                B^.LEFT:=TEM^.LEFT
             else
                B^.RIGHT:=TEM^.LEFT;
             P:=TEM;      {set P to disposed}
           end      {if node(P) has two children }
         else
         {reset one of the pointer fields of node(back)}
         {according to whether P has a right or left child}
           if P^.RIGHT <> nil then
             if B=NIL then
                R:=P^.RIGHT
             else
               if B^.RIGHT =P then
                  B^.RIGHT:=P^.RIGHT
               else
                 B^.LEFT:=P^.RIGHT
             else            {node(P) has a left child }
               if B=NIL then
                 R:=P^.LEFT
               else        {delete non root node}
                 if B^.RIGHT = P then
                      B^.RIGHT:=P^.LEFT
                 else
                     B^.LEFT:=P^.LEFT;
    dispose(P);             {free node(P)}
  end;             { of delete node }

procedure RETRIEVE(CURRENT:treepntr);
  begin
    if(CURRENT<> nil) and not(found) then
       if (CURRENT^.MNEMONIC = elt) then
         begin
           found:=true;
           temp:=current;
           WRITELN;
           WRITELN;
           WRITELN('      FOUND !  ');
           SOUND(440);
           DELAY(1000);
           NOSOUND;
           WRITELN;
           WRITELN;
           WRITELN('THE OPCODE IS :  ',CURRENT^.OPCODE);
           repeat until keypressed;
           exit;
         end
       else
         begin
           RETRIEVE(CURRENT^.LEFT);
           retrieve(CURRENT^.RIGHT)
         end;
  end;

begin  {main block}
  CLRSCR;
  textcolor(black);
  textbackground(white);
  ASSIGN(FIL,'CODE.PAS');
  CREATE(FIL);
  RESET(FIL);
  READ(FIL,DAT);
  new(current);
  CURRENT^.MNEMONIC:=DAT.MNEMONIC;
  CURRENT^.OPCODE:=DAT.OPCODE;
  CURRENT^.RIGHT:=NIL;
  first:=current;
  while not eof(FIL) do
    begin
      READ(FIL,DAT);
      elt:=dat.mnemonic;
      num:=dat.opcode;
      insert(first)
    end;
  WRITELN;
  repeat
    CLRSCR;
    WRITELN;
    WRITELN;
    WRITELN('       #    TREE OF MNEMONICS   # ');
    WRITELN;
    WRITELN;
    WRITELN('  THIS PROGRAM CREATES TREE OF SOME MNEMONICS ');
    WRITELN;
    WRITELN;
    WRITELN('    IT LETS YOU  ');
    WRITELN;
    WRITELN;
    WRITELN(' I : INSERT A MNEMONIC & ITS OPCODE');
    WRITELN;
    WRITELN(' D : DELETE A MNEMONIC & ITS OPCODE');
    WRITELN;
    WRITELN(' R : RETRIEVE A MNEMONIC & ITS OPCODE ');
    WRITELN;
    WRITELN(' Q : QUIT THE TREE ');
    WRITELN;
    WRITELN;
    WRITE(' ENTER YOUR CHOICE -->  ');
    READ(KBD,CHOICE);
    WRITELN;
    CHOICE:=upcase(CHOICE);
    current:=first;
    case CHOICE  of
       'I': begin
              CLRSCR;
              WRITELN;
              WRITELN;
              WRITELN('---------------------------------');
              WRITELN('        INSERT A MNEMONIC        ');
              WRITELN('---------------------------------');
              WRITELN;
              found:=false;
              WRITELN;
              WRITELN;
              WRITELN(' PRESS  << CAPSLOCK >>  ');
              WRITELN;
              WRITE('   ENTER THE MNEMONIC  :  ');
              READLN(ELT);
              RETRIEVE(FIRST);
              if not(found) then
                begin
                  WRITELN;
                  WRITELN;
                  WRITE( '  ENTER THE OPCODE :  ');
                  READLN(NUM);
                  INSERT(FIRST);
                  WRITELN;
                  WRITELN('  MNEMONIC SUCCESSFULLY INSERTED ');
                  repeat until keypressed;
                  CLRSCR;
                end
              else
               begin
                 WRITELN;
                 WRITELN(' DUPLICATE MNEMONIC  :  CANNOT INSERT ');
                 repeat until keypressed;
               end;
            end;
       'D': begin
               CLRSCR;
               WRITELN;
               WRITELN('-------------------------------');
               WRITELN('       DELETE A MNEMONIC       ');
               WRITELN('-------------------------------');
               WRITELN;
               FOUND:=TRUE;
               WRITELN;
               WRITELN;
               WRITELN(' PRESS  <<CAPSLOCK>>  ');
               WRITELN;
               RETRIEVE(FIRST);
               if (found) then
                  begin
                    WRITELN;
                    WRITELN;
                    DELETE(R,P,B);
                    WRITELN;
                    WRITELN;
                    WRITELN('  MNEMONIC SUCCESSFULLY DELETED ');
                    repeat until keypressed;
                  end
               else
                 begin
                   WRITELN('  MNEMONIC NOT FOUND ');
                   WRITELN;
                   WRITELN('  CANNOT DELETE  ');
                   repeat until keypressed;
                 end;
            end;
       'R': begin
              CLRSCR;
              WRITELN;
              WRITELN;
              WRITELN('---------------------------');
              WRITELN('    RETRIEVE A MNEMONIC    ');
              WRITELN('---------------------------');
              WRITELN;
              found:=false;
              WRITELN;
              WRITELN('  PRESS <<CAPSLOCK>>  ');
              WRITELN;
              WRITELN;
              WRITE('   ENTER THE MNEMONIC :  ');
              READLN(elt);
              RETRIEVE(FIRST);
              if not(found) then
                begin
                  WRITELN;
                  WRITELN;
                  WRITELN('   SORRY !  ');
                  WRITELN;
                  WRITELN;
                  WRITELN('  MNEMONIC NOT FOUND  ');
                  repeat until keypressed;
                end;
            end;
       'Q': begin
               CLRSCR;
               GOTOXY(0,17);
               WRITELN('================================');
               WRITELN;
               WRITELN(' RETURNING TO TURBO ............');
               WRITELN;
               WRITELN('================================');
               DELAY(3000);
               CLRSCR;
            end;
      end;
  until (choice='Q');
end.
